| Name | ModbusMaster |
|---|---|
| Version | 1 |
| Major release | 0 |
| Minor release | 8 |
| Title | Unit for implement a Modbus® master communication with extended addressing. |
The unit implement a complete data exchange of a Modbus master communication line. The main features are:
The large circles represent stable states. They are:
STOPPED: state where the unit does not perform any activity. It is also the initial state.
READY: state of full activity
ABORT: there is a serious error, the unit switches to the safe state and waits for a stop command. AbortCode provides an identification code of the reason that set that state.
The rectangles indicate transient states:
STARTING: state in which the unit checks all the settings data and if the values are within the limits opens the communication channel.
STOPPING: nothing do in this implementation.
ABORTING: nothing do in this implementation.
Baloons are commands that can be sent to change the state:
Prepare, commands the unit to switch into ready state. Prior to this command must be configured all the communication parameters.
Stop, commands the unit to switch into STOPPED state. The communication channel is closed if it was open.
The following table shows the Modbus standard functions that are available.
| Value | Constant | Description |
|---|---|---|
| 1 | READCOIL* | Reads the ON/OFF status of discrete outputs (coils) in the slave. |
| 3 | READREG | Reads the binary contents of holding registers in the slave. |
| 4 | READINREG | Reads the binary contents of input registers in the slave. |
| 5 | FORCECOIL* | Forces a single coil to either ON or OFF. |
| 6 | FORCEREG | Presets a value into a single holding register. |
| 15 | FORCEMCOIL* | Forces each coil in a sequence of coils to either ON or OFF. |
| 16 | FORCEMREG | Presets values into a sequence of holding registers. |
* These functions are currently selectable, but not yet fully developed.
It's a table that contains the communication parameters for each slave. You can enter the parameters for up to 32 slaves.
| SlaveId | SlaveBitrate | SlaveStopBits | SlaveParity | SlaveTimeout | SlaveAddrOffset | |
|---|---|---|---|---|---|---|
| row 1 | 2 | 38400 | 1 | 2 | 50 | 0 |
| row 2 | 15 | 9600 | 2 | 0 | 200 | 1 |
| … | ||||||
| row 32 |
Using TCPIP protocol:
| SlaveId | SlaveTcpAddr3 | SlaveTcpAddr2 | SlaveTcpAddr1 | SlaveTcpAddr0 | SlaveTcpChangeIpDly | SlaveAddrOffset | |
|---|---|---|---|---|---|---|---|
| row 1 | 1 | 192 | 168 | 0 | 20 | 100 | 0 |
| row 2 | 1 | 192 | 168 | 0 | 21 | 200 | 1 |
| … | |||||||
| row 32 |
SlaveId : It's the real ID of the Modbus protocol set in the slave.
SlaveBitrate : It's the baud rate (we support all values compatible with the device MODBUS).
SlaveStopBits : It's the stop bit (0,1,2).
SlaveParity : It's the parity (0 = NONE, 1 = ODD, 2 = EVEN).
SlaveTimeout : It's the maximum value of waiting for a response before reporting a timeout error.
SlaveAddrOffset : It's a value that is added to the address before sending the Modbus message. It's used for matching the numbering of the address used in the tables of this unit with the values shown in the documentation of the slave.
SlaveTcpAddr3 : It's the tcpip address position 3 [Highest] ⇒ 3.2.1.0
SlaveTcpAddr2 : It's the tcpip address position 2.
SlaveTcpAddr1 : It's the tcpip address position 1.
SlaveTcpAddr0 : It's the tcpip address position 0 [Lowest].
SlaveTcpChangeIpDly : It's a waiting time in milliseconds used at every tcpip address change [min. 1, default 500].
Once the SlaveId is entered into this table, it allows you to identify a slave with generic index which we will call from now on “Slave index” and which corresponds to the row of the table.
It's a configuration table for a communication of data process. The process values are stored on an array (called ProcessValue)
where each data element is located at a certain index value. The calculation of the index value for each data is done automatically by the unit based on the data of ProcessTable. The communication of process data can be enabled or disabled with the parameter ProcessEnable.
In order to optimize the occupation of the Modbus® channel, communication process can using multiple messages. Also you can place in ProcessTable write command messages.
An example of the communication process can be a reading of the statusword inverter, writing of the motor speed, reading of the torque value of the motor, reading the temperature value by a temperature controller, etc..
The ProcessTable has a size of 100 rows that must be used for the process data exchange of all slaves; the array ProcessValue has a size of 300 elements. When the unit encounters a line with ProcessId equal to zero, it resumes scanning from start (row 1). To suspend the communication of a specific row simply set ProcessId to a negative value.
ProcessTable
| ProcessId | ProcessAddr | ProcessNum | ProcessType | ProcessOffset | ProcessDevErr | |
|---|---|---|---|---|---|---|
| row 1 | 1 | 100 | 2 | 3 | 1 | |
| row 2 | 2 | 100 | 3 | 3 | 3 | |
| … | ||||||
| row 100 |
ProcessValue
| 1 | 2 | 3 | 4 | 5 | 6 | … | 300 |
|---|---|---|---|---|---|---|---|
| row 1 | row 1 | row 2 | row 2 | row 2 |
ProcessId : It's the slave index that indicates that you want to communicate with the slave whose parameters are represented by the row indicated by the value in SlaveTable.
ProcessAddr : It's the Modbus address.
ProcessNum : It's the number of elements (for multiple reading or writing).
ProcessType : It's the Modbus function type.
ProcessOffset : It's the ProcessValue array index where the values will start to be stored. This value is calculated automatically when you start the unit.
ProcessDevErr : It's the err parameter value of the device in the case of error communication.
It manages communication used to perform operations on slave configuration registers (call parameters). This table includes all the information needed to identify these parameters. It 'a single table for all slaves. This table can be included only the data manipulated by the message Modbus® 3 (read holding register) or 6 (force holding register). Are not possible communications using coils, inputs, inputs registers and multiple operations.
The size established for this table is to hold a maximum of 200 parameters.
To enable communication with the Param data type you must use the LowMailBox described below.
| ParamId | ParamAddr | ParamNum | ParamOptions | ParamValue | |
|---|---|---|---|---|---|
| row 1 | 1 | 200 | 1 | 0 | 11 |
| row 2 | 2 | 201 | 1 | 0 | 22 |
| … | |||||
| row 200 |
ParamId : It's the slave index that indicates that you want to communicate with the slave whose parameters are represented by the line indicated by the value in SlaveTable.
ParamAddr : It's the Modbus address.
ParamNum : Normally set to 1, the value is set 2 to treat certain 32bit data which are composed of two words Modbus®.
ParamOptions : You can specify some details about communication (shown below).
ParamValue : It's the read value or the value to be written.
ParamOptions
The ParamOptions is used to set certain communication characteristics. It runs with the following bit masks:
| Constant | Bit | Description |
|---|---|---|
| OPTION_SIZE | 0 | If true, it allows to perform writing parameter as a COIL. FORCECOIL (5) instead of FORCEREG (6) FORCEMCOIL (15) instead of FORCEMREG (16) |
| OPTION_MULTI | 1 | If true, it allows to perform writing parameters with size (num) 1 with Modbus multiple functions FORCEMCOIL (15) and FORCEMREG (16). |
| OPTION_ROUND | 2 | If true, it allows to tolerate differences of 1 unit during check parameters commands (the value in the slave can be less by one unit spite the value in the table). It has been seen that some slaves execute internal roundings processing of numerical values received via Modbus for which a value previously written does not match the value reread. |
It's a technique of traffic light system for communication between the various units. This unit includes two Mailbox, the HighMbox and LowMbox.
This character allows to various units of the Qview project to share with simplicity the Modbus® communication.
Here's an example:
Both HighMbox and LowMbox are an array of 38 elements, that will be explained subsequently.
In HighMbox[1] and LowMbox[1], there are states and commands to mailboxes:
| Value | Constant | Desciption |
|---|---|---|
| 0 | MBOX_FREE | Mailbox is free to be used. |
| 1 | MBOX_REPLY | Mailbox reply. |
| 2 | MBOX_SINGLE_REQUEST | Mailbox single request. |
| 3 | MBOX_PARAM_CHECK | Mailbox command to check all parameters of a single slave. Only for LowMbox. |
| 4 | MBOX_PARAM_CHECK_ALL | Mailbox command to check all parameters of all slaves. Only for LowMbox. |
| 5 | MBOX_PARAM_READ | Mailbox command to read all parameters of a single slave. Only for LowMbox. |
| 6 | MBOX_PARAM_WRITE | Mailbox command to write all parameters of a single slave. Only for LowMbox. |
The variable LowMboxProgress is updated during LowMbox commands and takes values from 0 to 100 to indicate the progress of the operation. It can be used in hmi to manage a progressbar.
| HighMbox[1] | 0 → MBOX_FREE 1 → MBOX_REPLY 2 → MBOX_SINGLE_REQUEST |
|
| HighMbox[2..38] | The meaning depends on the content of the element [1] in the following way: | |
| HighMbox[1] = MBOX_REPLY | HighMbox[1] = MBOX_SINGLE_REQUEST | |
|---|---|---|
| HighMbox[2] | slave index | |
| HighMbox[3] | address | |
| HighMbox[4] | type | |
| HighMbox[5] | num | |
| HighMbox[6] | return value 0 = OK 1 = error in communication 4 = error in opening or closing the COM port 5 = slave index out of range 6 = modbus type not valid | tout (it can be put to zero, in which case it will use the value in the slave table SlaveTimeout. If this were zero then it uses a default value equal to 100 msec) |
| HighMbox[7..38] | values of the registers (in the case of reading) | values of the registers (in the case of writing) |
We see a sample code for any unit that wants to perform a read:
WAIT MDBMAST1.HighMbox[1] EQ MDBMAST1.MBOX_FREE ; wait for empty mailbox
MDBMAST1.HighMbox[2] = 1 ; first slave in configuration table
MDBMAST1.HighMbox[3] = 100 ; address
MDBMAST1.HighMbox[4] = MDBMAST1.READINREG ; type
MDBMAST1.HighMbox[5] = 5 ; num
MDBMAST1.HighMbox[6] = 0 ; tout (use default)
MDBMAST1.HighMbox[1] = MDBMAST1.MBOX_SINGLE_REQUEST ; start request
WAIT MDBMAST1.HighMbox[1] EQ MDBMAST1.MBOX_REPLY ; wait for reply
IF MDBMAST1.HighMbox[6] EQ 0 ; successfully ?
Myvar = MDBMAST1.HighMbox[7]
ENDIF
MDBMAST1.HighMbox[1] = MDBMAST1.MBOX_FREE ; mailbox is now free for other units
We can do the same function with LowMbox (the difference between High and Low will be explained subsequently).
| LowMbox[1] | 0 → MBOX_FREE 1 → MBOX_REPLY 2 → MBOX_SINGLE_REQUEST |
|
| LowMbox[2..38] | The meaning depends on the content of the element [1] in the following way: | |
| LowMbox[1] = MBOX_REPLY | LowMbox[1] = MBOX_SINGLE_REQUEST | |
|---|---|---|
| LowMbox[2] | slave index | |
| LowMbox[3] | address | |
| LowMbox[4] | type | |
| LowMbox[5] | num | |
| LowMbox[6] | return value 0 = OK 1 = error in communication 4 = error in opening or closing the COM port 5 = slave index out of range 6 = modbus type not valid | tout (it can be put to zero, in which case it will use the value in the slave table SlaveTimeout. If this were zero then it uses a default value equal to 100 msec) |
| LowMbox[7..38] | values of the registers (in the case of reading) | values of the registers (in the case of writing) |
The function checks the parameters of a slave if they coincide with the values contained in ParamValue.
| LowMbox[1] | 0 → MBOX_FREE 1 → MBOX_REPLY 3 → MBOX_PARAM_CHECK |
|
| LowMbox[2..38] | The meaning depends on the content of the element [1] in the following way: | |
| LowMbox[1] = MBOX_REPLY | LowMbox[1] = MBOX_PARAM_CHECK | |
|---|---|---|
| LowMbox[2] | slave index | |
| LowMbox[6] | return value 0 = OK 1 = error in communication 2 = error in parameter verification 3 = no parameter of selected slave found in the table 4 = error in opening or closing the COM port 5 = slave index out of range | tout (it can be put to zero, in which case it will use the value in the slave table SlaveTimeout. If this were zero then it uses a default value equal to 100 msec) |
| LowMbox[7] | In the case of LowMbox [6] = 2, is shown the address of the first parameter that has generated the error | |
| LowMbox[8] | In the case of LowMbox [6] = 2, is shown the value read from the slave of the parameter that caused the error | |
| LowMbox[9] | In the case of LowMbox [6] = 2, is shown the value in table of the parameter that caused the error | |
The function checks the parameters of all slaves if they coincide with the values contained in ParamValue.
| LowMbox[1] | 0 → MBOX_FREE 1 → MBOX_REPLY 4 → MBOX_PARAM_CHECK_ALL |
|
| LowMbox[2..38] | The meaning depends on the content of the element [1] in the following way: | |
| LowMbox[1] = MBOX_REPLY | LowMbox[1] = MBOX_PARAM_CHECK_ALL | |
|---|---|---|
| LowMbox[2] | slave index | |
| LowMbox[6] | return value 0 = OK 1 = error in communication 2 = error in parameter verification 3 = no parameter of selected slave found in the table 4 = error in opening or closing the COM port 5 = slave index out of range | tout (it can be put to zero, in which case it will use the value in the slave table SlaveTimeout. If this were zero then it uses a default value equal to 100 msec) |
| LowMbox[7] | In the case of LowMbox [6] = 2, is shown the address of the first parameter that has generated the error | |
| LowMbox[8] | In the case of LowMbox [6] = 2, is shown the value read from the slave of the parameter that caused the error | |
| LowMbox[9] | In the case of LowMbox [6] = 2, is shown the value in table of the parameter that caused the error | |
| LowMbox[10] | In the case of LowMbox [6] = 2, is shown the slave index of the parameter that caused the error | |
The function reads the parameters of a slave and stores them in ParamValue.
| LowMbox[1] | 0 → MBOX_FREE 1 → MBOX_REPLY 5 → MBOX_PARAM_READ |
|
| LowMbox[2..38] | The meaning depends on the content of the element [1] in the following way: | |
| LowMbox[1] = MBOX_REPLY | LowMbox[1] = MBOX_PARAM_READ | |
|---|---|---|
| LowMbox[2] | slave index | |
| LowMbox[6] | return value 0 = OK 1 = error in communication 3 = no parameter of selected slave found in the table 4 = error in opening or closing the COM port 5 = slave index out of range | tout (it can be put to zero, in which case it will use the value in the slave table SlaveTimeout. If this were zero then it uses a default value equal to 100 msec) |
| LowMbox[7] | In the case of LowMbox [6] = 1, is shown the address of the parameter that caused the error in communication | |
| LowMbox[8] | In the case of LowMbox [6] = 1, is shown the last word read by the device MODBUS | |
| LowMbox[9] | In the case of LowMbox [6] = 1, is shown the error code of the device MODBUS | |
The function writes the parameters of a slave with the values stored in ParamValue.
| LowMbox[1] | 0 → MBOX_FREE 1 → MBOX_REPLY 6 → MBOX_PARAM_WRITE |
|
| LowMbox[2..38] | The meaning depends on the content of the element [1] in the following way: | |
| LowMbox[1] = MBOX_REPLY | LowMbox[1] = MBOX_PARAM_WRITE | |
|---|---|---|
| LowMbox[2] | slave index | |
| LowMbox[6] | return value 0 = OK 1 = error in communication 3 = no parameter of selected slave found in the table 4 = error in opening or closing the COM port 5 = slave index out of range | tout (it can be put to zero, in which case it will use the value in the slave table SlaveTimeout. If this were zero then it uses a default value equal to 100 msec) |
| LowMbox[7] | In the case of LowMbox [6] = 1, is shown the address of the parameter that caused the error in communication | |
| LowMbox[8] | In the case of LowMbox [6] = 1, is shown the last word written by the device MODBUS | |
| LowMbox[9] | In the case of LowMbox [6] = 1, is shown the error code of the device MODBUS | |
The difference between HighMbox and LowMbox consists in the fact that the HighMbox has the possibility of entering during a multiple request commanded on LowMbox, in order to have always the possibility of swift action on variables of high priority.
Let's see how the priority of requests are menaged. Denote by:
P = request regarding the ProcessTable
H = request regarding the HighMbox
L = request regarding the LowMbox



Below there are some tables with an explanation of the public symbols.
| Name | Type | Size | Access Type | Description |
|---|---|---|---|---|
| Prepare | GLOBAL | F | IN | Command to set STARTING state, after all configuration tables were compiled. |
| Stop | GLOBAL | F | INOUT | Command to set STOPPING state. |
| ProcessEnable | GLOBAL | F | INOUT | Enable for process requests. |
| ProcessErrReset | GLOBAL | F | INOUT | Command to reset all the errors of ProcessTable. |
| StatReset | GLOBAL | F | INOUT | Command to reset all the values concerning statistics. |
| HighMbox[1] LowMbox[1] | ARRGBL | W | INOUT | Commands to mailboxes : (2) MBOX_SINGLE_REQUEST (3) MBOX_PARAM_CHECK (4) MBOX_PARAM_CHECK_ALL (5) MBOX_PARAM_READ (6) MBOX_PARAM_WRITE Commands 3,4,5,6 are available only for LowMbox. It should be set to (0) MBOX_FREE when a request is completed. |
| HighMbox[2] LowMbox[2] | ARRGBL | W | INOUT | Slave index. |
| HighMbox[3] LowMbox[3] | ARRGBL | W | INOUT | Modbus address (only for MBOX_SINGLE_REQUEST). |
| HighMbox[4] LowMbox[4] | ARRGBL | W | INOUT | Modbus function (only for MBOX_SINGLE_REQUEST). 1, 3, 4, 5, 6, 15, 16 |
| HighMbox[5] LowMbox[5] | ARRGBL | W | INOUT | Modbus elements number (only for MBOX_SINGLE_REQUEST). |
| HighMbox[6] LowMbox[6] | ARRGBL | W | INOUT | Timeout modbus reply. |
| HighMbox[7..38] LowMbox[7..38] | ARRGBL | W | INOUT | Data area (in MBOX_SINGLE_REQUEST). |
| Name | Type | Size | Access Type | Description |
|---|---|---|---|---|
| State | GLOBAL | B | OUT | Actual state. The values can be STOPPED (0), STARTING (1), READY (2), ABORTING (3), ABORTED (4), STOPPING (5) |
| ProcessError | GLOBAL | F | OUT | Modbus error during a request of process loop; it remains active until it is set to 0 by the command ProcessErrReset. |
| LowMboxProgress | GLOBAL | B | OUT | Rate of progression in parameters LowMbox functions. |
| HighMbox[1] LowMbox[1] | ARRGBL | W | INOUT | Mailboxes states. (0) MBOX_FREE (1) MBOX_REPLAY (2..6) active request |
| HighMbox[6] LowMbox[6] | ARRGBL | W | INOUT | Return value. 0 = OK 1 = error in communication 2 = error in parameter verification 3 = no parameter of selected slave found in the table 4 = error in opening or closing the COM port |
| HighMbox[7..38] LowMbox[7..38] | ARRGBL | W | INOUT | Data area in requests without errors (in MBOX_SINGLE_REQUEST). |
| LowMbox[7] | ARRGBL | W | INOUT | MBOX_SINGLE_REQUEST → not used MBOX_PARAM_CHECK and MBOX_PARAM_CHECK_ALL In the case of LowMbox [6] = 2, is shown the address of the first parameter that has generated the error. MBOX_PARAM_READ and MBOX_PARAM_WRITE In the case of LowMbox [6] = 1, is shown the address of the parameter that caused the error in communication. |
| LowMbox[8] | ARRGBL | W | INOUT | MBOX_SINGLE_REQUEST → not used MBOX_PARAM_CHECK and MBOX_PARAM_CHECK_ALL In the case of LowMbox [6] = 2, is shown the value read from the slave of the parameter that caused the error. MBOX_PARAM_READ and MBOX_PARAM_WRITE In the case of LowMbox [6] = 1, is shown the last word read or written by the device MODBUS. |
| LowMbox[9] | ARRGBL | W | INOUT | MBOX_SINGLE_REQUEST → not used MBOX_PARAM_CHECK and MBOX_PARAM_CHECK_ALL In the case of LowMbox [6] = 2, is shown the value in table of the parameter that caused the error. MBOX_PARAM_READ and MBOX_PARAM_WRITE In the case of LowMbox [6] = 1, is shown the error code of the device MODBUS. |
| LowMbox[10] | ARRGBL | W | INOUT | MBOX_SINGLE_REQUEST, MBOX_PARAM_CHECK, MBOX_PARAM_READ and MBOX_PARAM_WRITE → not used MBOX_PARAM_CHECK_ALL In the case of LowMbox [6] = 2, is shown the slave index of the parameter that caused the error. |
| Statistics | ||||
| TotalStatCommOk | GLOBAL | L | OUT | Counter all requests completed without errors. |
| TotalStatAttempt | GLOBAL | L | OUT | Counter all attempts performed in completed requests without errors. |
| TotalStatCommKo | GLOBAL | L | OUT | Counter all requests not completed for exceeding the maximum number of attempts. |
| TotalStatWrong | GLOBAL | L | OUT | Counter all requests not completed for a Modbus request error. |
| UpdateProcessTime | GLOBAL | L | OUT | Current update time of all process table. |
| Stat table | ||||
| StatCommOk | ARRGBL | L | OUT | Counter of requests completed without error for each Modbus node. |
| StatAttempt | ARRGBL | L | OUT | Counter all attempts performed in completed requests without errors for each Modbus node. |
| StatCommKo | ARRGBL | L | OUT | Counter all requests not completed for exceeding the maximum number of attempts for each Modbus node. |
| StatWrong | ARRGBL | L | OUT | Counter all requests not completed for a Modbus request error for each Modbus node. |
| StatMaxReplyTime | ARRGBL | W | OUT | Maximum time (msec) for requests completed without attempts for each Modbus node. |
| Name | Type | Size | Access Type | Description |
|---|---|---|---|---|
| Protocol | GLOBAL | B | IN | Device MODBUS protocol selection. (0) = DEVICE_PROT_ASCII (1) = DEVICE_PROT_RTU (2) = DEVICE_PROT_TCPIP) |
| TcpIpPort | GLOBAL | W | INOUT | TCPIP communication port. Used only with Protocol = DEVICE_PROT_TCPIP, defines the communication port for messages. If this parameter is left to zero, the unit uses the default value of the Modbus protocol (502). |
| MaxAttempts | GLOBAL | B | INOUT | Maximum number of attempts. |
| RelaxTime | GLOBAL | L | INOUT | Waiting time (msec) between an attempt and another (default = 200) |
| Slave table | ||||
| SlaveId | ARRGBL | W | INOUT | The real ID of the Modbus protocol set in the slave. |
| SlaveBitrate | ARRGBL | L | INOUT | The baud rate (we support all values compatible with the device MODBUS). |
| SlaveStopBits | ARRGBL | B | INOUT | The stop bit (0,1,2). |
| SlaveParity | ARRGBL | B | INOUT | The parity (0 = NONE, 1 = ODD, 2 = EVEN). |
| SlaveTimeout | ARRGBL | W | INOUT | The maximum value of waiting for a response before reporting a timeout error. |
| SlaveAddrOffset | ARRGBL | B | INOUT | A value that is added to the address before sending the Modbus message. It's used for matching the numbering of the address used in the tables of this unit with the values shown in the documentation of the slave. |
| SlaveTcpAddr3 | ARRGBL | W | INOUT | Tcpip address position 3 [Highest] ⇒ 3.2.1.0 |
| SlaveTcpAddr2 | ARRGBL | W | INOUT | Tcpip address position 2. |
| SlaveTcpAddr1 | ARRGBL | W | INOUT | Tcpip address position 1. |
| SlaveTcpAddr0 | ARRGBL | W | INOUT | Tcpip address position 0 [Lowest]. |
| SlaveTcpChangeIpDly | ARRGBL | L | INOUT | A waiting time in milliseconds when the new request is for another tcpip slave [min. 1, default 500]. |
| Param table | ||||
| ParamId | ARRGBL | W | INOUT | The slave index that indicates that you want to communicate with the slave whose parameters are represented by the line indicated by the value in SlaveTable. |
| ParamAddr | ARRGBL | W | INOUT | The Modbus address. |
| ParamNum | ARRGBL | W | INOUT | Normally set to 1, the value is set 2 to treat certain 32bit data which are composed of two words Modbus®. |
| ParamOptions | ARRGBL | B | INOUT | You can specify some details about communication (shown in relative chapter). |
| ParamValue | ARRGBL | L | INOUT | The value read or the value to be written. |
| Process table | ||||
| ProcessId | ARRGBL | W | INOUT | The slave index that indicates that you want to communicate with the slave whose parameters are represented by the line indicated by the value in SlaveTable. |
| ProcessAddr | ARRGBL | W | INOUT | The Modbus address. |
| ProcessNum | ARRGBL | W | INOUT | The number of elements (for multiple reading or writing). |
| ProcessType | ARRGBL | W | INOUT | The Modbus function type. |
| ProcessOffset | ARRGBL | W | INOUT | The ProcessValue array index where the values will start to be stored. This value is calculated automatically when you start the unit. |
| ProcessDevErr | ARRGBL | B | OUT | The err parameter value of the device in the case of error communication. |
| ProcessValue | ARRGBL | L | INOUT | In this area is stored the value read or to be written. |
| Name | Value | Description |
|---|---|---|
| States | ||
| STOPPED | 0 | State where the unit does not perform any activity. It is also the initial state. |
| STARTING | 1 | State in which the unit checks all the settings data and if the values are within the limits opens the communication channel. |
| READY | 2 | State of full activity. |
| ABORTING | 3 | Nothing do in this implementation. |
| ABORTED | 4 | There is a serious error, the unit switches to the safe state and waits for a stop command. AbortCode provides an identification code of the reason that set that state. |
| STOPPING | 5 | Nothing do in this implementation. |
| Modbus protocol | ||
| DEVICE_PROT_ASCII | 0 | MODBUS ASCII protocol. |
| DEVICE_PROT_RTU | 1 | MODBUS RTU protocol. |
| DEVICE_PROT_TCPIP | 2 | MODBUS TCPIP protocol. |
| Modbus functions types | ||
| READCOIL | 1 | Reads the ON/OFF status of discrete outputs (coils) in the slave. |
| READREG | 3 | Reads the binary contents of holding registers in the slave. |
| READINREG | 4 | Reads the binary contents of input registers in the slave. |
| FORCECOIL | 5 | Forces a single coil to either ON or OFF. |
| FORCEREG | 6 | Presets a value into a single holding register. |
| FORCEMCOIL | 15 | Forces each coil in a sequence of coils to either ON or OFF. |
| FORCEMREG | 16 | Presets values into a sequence of holding registers. |
| Param table request options | ||
| OPTION_SIZE | &H01 | If checked, it allows you to perform writing parameter as a COIL. FORCECOIL (5) instead of FORCEREG (6) FORCEMCOIL (15) instead of FORCEMREG (16) |
| OPTION_MULTI | &H02 | If checked, it allows you to perform writing parameters with size (num) 1 with Modbus multiple functions FORCEMCOIL (15) and FORCEMREG (16). |
| OPTION_ROUND | &H04 | If this option is set, it allows to tolerate during the commands of check parameters differences of 1 unit (the value in the slave can be less by one unit spite the value in the table). It has been seen that some slaves execute internal roundings processing of numerical values received via Modbus for which a value previously written does not match the value reread. |
| Mailboxes states and commands | ||
| MBOX_FREE | 0 | Mailbox is free to be used. |
| MBOX_REPLY | 1 | Mailbox reply. |
| MBOX_SINGLE_REQUEST | 2 | Mailbox single request. |
| MBOX_PARAM_CHECK | 3 | Mailbox command to check all parameters of a single slave. Only for LowMbox. |
| MBOX_PARAM_CHECK_ALL | 4 | Mailbox command to check all parameters of all slaves. Only for LowMbox. |
| MBOX_PARAM_READ | 5 | Mailbox command to read all parameters of a single slave. Only for LowMbox. |
| MBOX_PARAM_WRITE | 6 | Mailbox command to write all parameters of a single slave. Only for LowMbox. |
To better understand the operation of this unit, we will see how to configure it and use it for a simple management of 2 drives. This type of example demonstrates well the potential of this unit. In fact, after setting up the slave, we're going to set some process data to read and write all the time, we're going to set a table of parameters with which to interface, and we're going to intervene with the use of the mailbox on situations that need a immediate action.
INTDEVICE
MdbDevice MODBUS 0008 1
Pay attention to the last field number of the declaration (1) that is used to select the communication port. Usually it is 0 for PROG port, 1 for USER port, 2 for aux1, 3 for aux2 port and 43 for ethernet port (modbus tcpip). Check hardware manual for assurance.
REFERENCES
MDBMAST1.modbus = MdbDevice
MDBMAST1.Protocol = MDBMAST1.DEVICE_PROT_RTU ; modbus rtu
; setting unit ModbusMaster10 slave table
; node 1
MDBMAST1.SlaveId[1] = 1
MDBMAST1.SlaveBitrate[1] = 9600
MDBMAST1.SlaveStopBits[1] = 1
MDBMAST1.SlaveParity[1] = 0
MDBMAST1.SlaveTimeout[1] = 200
MDBMAST1.SlaveAddrOffset[1] = 0
; node 2
MDBMAST1.SlaveId[2] = 3
MDBMAST1.SlaveBitrate[2] = 57600
MDBMAST1.SlaveStopBits[2] = 2
MDBMAST1.SlaveParity[2] = 1
MDBMAST1.SlaveTimeout[2] = 100
MDBMAST1.SlaveAddrOffset[2] = 1
Our network is RTU and consists of 2 drives, one with id 1 and the other with id 3, with different communication settings.
; setting unit ModbusMaster10 process table
; read current speed of slave index 1
MDBMAST1.ProcessId[1] = 1 ; slave index (in slave table)
MDBMAST1.ProcessAddr[1] = &H102B ; exadecimal address value
MDBMAST1.ProcessNum[1] = 1 ; number of elements
MDBMAST1.ProcessType[1] = MDBMAST1.READINREG ; type of modbus request
; write set speed of slave index 1
MDBMAST1.ProcessId[2] = 1
MDBMAST1.ProcessAddr[2] = &H0060
MDBMAST1.ProcessNum[2] = 1
MDBMAST1.ProcessType[2] = MDBMAST1.FORCEREG
; read current state of slave index 1
MDBMAST1.ProcessId[3] = 1
MDBMAST1.ProcessAddr[3] = &H00A8
MDBMAST1.ProcessNum[3] = 1
MDBMAST1.ProcessType[3] = MDBMAST1.READINREG
; read current speed of slave index 2
MDBMAST1.ProcessId[4] = 2
MDBMAST1.ProcessAddr[4] = &H102B
MDBMAST1.ProcessNum[4] = 1
MDBMAST1.ProcessType[4] = MDBMAST1.READINREG
; write set speed of slave index 2
MDBMAST1.ProcessId[5] = 2
MDBMAST1.ProcessAddr[5] = &H0060
MDBMAST1.ProcessNum[5] = 1
MDBMAST1.ProcessType[5] = MDBMAST1.FORCEREG
; read current state of slave index 2
MDBMAST1.ProcessId[6] = 2
MDBMAST1.ProcessAddr[6] = &H00A8
MDBMAST1.ProcessNum[6] = 1
MDBMAST1.ProcessType[6] = MDBMAST1.READINREG
; setting unit ModbusMaster10 param table
; first parameter of the list (slave index 1)
MDBMAST1.ParamId[1] = 1 ; slave index (in slave table)
MDBMAST1.ParamAddr[1] = &H1070 ; exadecimal address value
MDBMAST1.ParamNum[1] = 1 ; number of elements (maximum 2, to manage double word parameters)
MDBMAST1.ParamOptions[1] = MDBMAST1.OPTION_MULTI ; parameter option (use multiple modbus write function)
; second parameter of the list (slave index 1)
MDBMAST1.ParamId[2] = 1
MDBMAST1.ParamAddr[2] = &H1071
MDBMAST1.ParamNum[2] = 1
MDBMAST1.ParamOptions[2] = 0
; third parameter of the list (slave index 2)
MDBMAST1.ParamId[3] = 2
MDBMAST1.ParamAddr[3] = &H1070
MDBMAST1.ParamNum[3] = 1
MDBMAST1.ParamOptions[3] = MDBMAST1.OPTION_MULTI
; fourth parameter of the list (slave index 2)
MDBMAST1.ParamId[4] = 1
MDBMAST1.ParamAddr[4] = &H1071
MDBMAST1.ParamNum[4] = 1
MDBMAST1.ParamOptions[4] = 0
; execute unit command Prepare
MDBMAST1.Prepare = 1
WAIT (MDBMAST1.State EQ MDBMAST1.READY) OR (MDBMAST1.State EQ MDBMAST1.ABORTED)
IF MDBMAST1.State EQ MDBMAST1.ABORTED
MDBMAST1.Stop = 1 ; in case of error return to STOPPED state
... ; insert the code to notify the error
ELSE
MDBMAST1.ProcessEnable = 1 ; process requests can start
ENDIF
To manage the process values, use the array ProcessValue:
Drive1Vel = MDBMAST1.ProcessValue[MDBMAST1.ProcessOffset[1]] ; reading current speed MDBMAST1.ProcessValue[MDBMAST1.ProcessOffset[2]] = Drive1SetVel ; writing set speed Drive1State = MDBMAST1.ProcessValue[MDBMAST1.ProcessOffset[3]] ; reading current state Drive2Vel = MDBMAST1.ProcessValue[MDBMAST1.ProcessOffset[4]] MDBMAST1.ProcessValue[MDBMAST1.ProcessOffset[5]] = Drive2SetVel Drive2State = MDBMAST1.ProcessValue[MDBMAST1.ProcessOffset[6]]
ProcessOffset automatically calculates the position of the process element on the array.
In our example, we imagine to use the ParamTable once the drives are fully configured and ready to use. We decide the parameters that we could modify through our application. At this point at least the first time we go to read these parameters, and we have to save them in our retentive area.
The next code example shows how to read all parameters from second drive:
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_FREE ; wait until the mailbox is free
MDBMAST1.LowMbox[2] = 2 ; select slave index 2
MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_PARAM_READ ; read parameters function
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_REPLY ; wait until the function ends and replies
IF MDBMAST1.LowMbox[6] EQ 0
... ; read parameters successfully (message, change page, etc.)
slDrive2Par1 = MDBMAST1.ParamValue[3] ; store the read value on ritentive variable
slDrive2Par2 = MDBMAST1.ParamValue[4]
ELSE
... ; insert the code to menage errors
ENDIF
MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_FREE ; release mailbox
Normally at power, when you enable the connection of a Modbus network drives it is sometimes useful to analyze whether the parameters in the memory are aligned with those on the drives. To do this, we can use the corresponding commands of the mailbox:
MDBMAST1.ParamValue[1] = slDrive1Par1 ; load ritentive value on ParamValue array
MDBMAST1.ParamValue[2] = slDrive1Par2
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_FREE ; wait until the mailbox is free
MDBMAST1.LowMbox[2] = 1 ; select slave index
MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_PARAM_CHECK ; check parameters function
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_REPLY ; wait until the function ends and replies
IF MDBMAST1.LowMbox[6] EQ 0
... ; check parameters successfully (message, change page, etc.)
ELSE
... ; insert the code to menage errors
ENDIF
MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_FREE ; release mailbox
You can also use the function MBOX_PARAM_CHECK_ALL to check all parameters of all slaves with a single command.
Finally, we use the write command to set the parameters on the first and on the second drive:
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_FREE ; wait until the mailbox is free
MDBMAST1.ParamValue[1] = slDrive1Par1 ; load ritentive value on ParamValue array
MDBMAST1.ParamValue[2] = slDrive1Par2
MDBMAST1.ParamValue[3] = slDrive2Par1
MDBMAST1.ParamValue[4] = slDrive2Par2
MDBMAST1.LowMbox[2] = 1 ; select slave index 1
MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_PARAM_WRITE ; write parameters function
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_REPLY ; wait until the function ends and replies
IF MDBMAST1.LowMbox[6] EQ 0
... ; write parameters successfully (message, change page, etc.)
ELSE
... ; insert the code to menage errors
ENDIF
MDBMAST1.LowMbox[2] = 2 ; select slave index 2
MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_PARAM_WRITE ; write parameters function
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_REPLY ; wait until the function ends and replies
IF MDBMAST1.LowMbox[6] EQ 0
... ; write parameters successfully (message, change page, etc.)
ELSE
... ; insert the code to menage errors
ENDIF
MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_FREE ; release mailbox
Some parameters cannot be written in certain states of the drive.
First read the drive documentation.
In our example, each unit of a project has the possibility of using single requests for information, to set reference values, or force states of the drives. For these applications we offer 2 mailbox. Why 2 mailbox?
Basically to have two priorities for intervention.
If we use the HighMbox (high priority), we are going to intervene immediately after the current request, which is a read/write process, which is a request to check/read/write parameters, or other demands on LowMbox (low priority) from other units.
This feature was implemented considering the fact that some information must travel as quickly as possible, in our case we can say that in the event of an alarm condition must intervene immediately disabling drives.
Instead, the single requests on LowMbox are used for information that can wait for a while to be completed.
UNIT 1 - low priority request
For example, read some temperatures.
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_FREE ; wait until the mailbox is free
MDBMAST1.LowMbox[2] = 1 ; select slave index
MDBMAST1.LowMbox[3] = &H00A4 ; address (&H = hexadecimal)
MDBMAST1.LowMbox[4] = MDBMAST1.READREG ; read holding register modbus function
MDBMAST1.LowMbox[5] = 4 ; number of elements (read from &H00A4 to &H00A7)
MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_SINGLE_REQUEST ; single request function
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_REPLY ; wait until the function ends and replies
IF MDBMAST1.LowMbox[6] EQ 0
temperature[1] = MDBMAST1.LowMbox[7] ; store the read values on array
temperature[2] = MDBMAST1.LowMbox[8]
temperature[3] = MDBMAST1.LowMbox[9]
temperature[4] = MDBMAST1.LowMbox[10]
ELSE
... ; insert the code to menage errors
ENDIF
MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_FREE ; release mailbox
UNIT 2 - high priority request
For example, disable drive for an alarm condition.
IF Alarm
WAIT MDBMAST1.HighMbox[1] EQ MDBMAST1.MBOX_FREE ; wait until the mailbox is free
MDBMAST1.HighMbox[2] = 2 ; select slave index
MDBMAST1.HighMbox[3] = &H0009 ; address (&H = hexadecimal)
MDBMAST1.HighMbox[4] = MDBMAST1.FORCEREG ; write holding register modbus function
MDBMAST1.HighMbox[5] = 1 ; number of elements
MDBMAST1.HighMbox[7] = &0474 ; example value in state register to disable drive
MDBMAST1.HighMbox[1] = MDBMAST1.MBOX_SINGLE_REQUEST ; single request function
WAIT MDBMAST1.HighMbox[1] EQ MDBMAST1.MBOX_REPLY ; wait until the function ends and replies
IF MDBMAST1.HighMbox[6] EQ 0
NOP ; not operation
ELSE
... ; insert the code to menage errors
ENDIF
ENDIF
UNIT 3 - low priority request
For example, write a new setpoint on drive.
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_FREE ; wait until the mailbox is free
MDBMAST1.LowMbox[2] = 1 ; select slave index
MDBMAST1.LowMbox[3] = &H88AF ; address (&H = hexadecimal)
MDBMAST1.LowMbox[4] = MDBMAST1.FORCEREG ; write holding register modbus function
MDBMAST1.LowMbox[5] = 1 ; number of elements
MDBMAST1.LowMbox[7] = 5600 ; new setpoint value
MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_SINGLE_REQUEST ; single request function
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_REPLY ; wait until the function ends and replies
IF MDBMAST1.LowMbox[6] EQ 0
NOP ; not operation
ELSE
... ; insert the code to menage errors
ENDIF
MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_FREE ; release mailbox
WAIT MDBMAST1.LowMbox[1] EQ MDBMAST1.MBOX_FREE ; wait until the mailbox is free ... ; request MDBMAST1.LowMbox[1] = MDBMAST1.MBOX_FREE ; at the end release the mailbox
| QCL feature release | Description | Note | Date |
|---|---|---|---|
| 1.0.8 | Constants to select mailbox functions | 01/09/2015 |
Click here to download unit and examples.
Zip contents:
| Filename | Description |
|---|---|
| MDBMAST1.UNT | Qcl feature file |
| MODBUS_SLAVE_SERIAL_EXAMPLE.Qm6 | Example for serial communication |
| MODBUS_SLAVE_TCPIP_EXAMPLE.Qm6 | Example for server TCPIP communication |